const util = require('../util');


//请求转发器，统一格式：{forward:function}，返回一个promise
const forwarder = {
  get: require('./forward_get'),
  post: require('./forward_post'),
  json: require('./forward_json')
};

//响应的通知回调，暂时只有一个，统一格式：{notice:function}，返回一个promise
const noticeBack = require('./notice_back');

const logger = util.logger;

/**
 * 文件分类器
 * 判断文件类型，分发到不同的服务中执行
 */

/**
 * 校验转发插件是否存在
 */
function checkForwardMethod(method){
  if (!forwarder[method]){
    return util.getErrMsg('method_not_found');
  }
}

module.exports = {
  checkForwardMethod,
  //转发请求，处理request 文件
  send: async (filePath, list)=>{
    let fix = filePath.split('.').pop();
    switch(fix){
      case util.REQUEST:
        for (let element of list){
          let fileSeq = element.sequence;
          let fileJson = element.data;

          if (checkForwardMethod(fileJson.method)){
            logger.error('错误的 method :' + fileJson.method);
            continue;
          }

          //转发请求，此处要使用非阻塞的方式发送数据，防止一个请求占用时间过长，导致后续请求无法执行
          forwarder[fileJson.method].forward(fileJson).then((data) => {
            logger.debug(`请求文件 ${filePath} 处理成功，写成功 response 文件`);

            //创建响应文件
            util.pushResponse(fileSeq, {
              header: util.sucResMsg,
              content: data,
              back_url: fileJson.back_url
            });
            logger.debug(`响应文件 ${fileSeq} 写入成功。`);
          }).catch((e) => {
            //异常情况，只有http请求出现异常时，才算做异常，业务异常不在此处理
            logger.error(`请求文件 ${filePath} 处理异常，写异常 response 文件:`, e.stack||e);

            //创建响应文件
            util.pushResponse(fileSeq, {
              header: util.getErrMsg('request_send_fail'),    //处理request文件时发送请求异常
              content: e.stack,
              back_url: fileJson.back_url
            });
            logger.debug(`响应文件 ${fileSeq} 写入成功。`);
          });

        }
        //删除请求文件
        await util.removeFile(filePath);
        break;

      //响应通知，处理response文件。
      //通知失败时暂时还未加入重发处理
      case util.RESPONSE:
        for (let element of list){
          let fileSeq = element.sequence;
          let fileJson = element.data;
          if (fileJson.back_url){
            // back_url 不为空，异步请求，发送通知请求
            noticeBack.notice(fileSeq, fileJson).then((data) => {
              logger.debug(`响应文件 ${filePath} 通知成功返回：`, data);
              if (data.header && data.header.code === 'success' || data.head && data.head.response_code === '000000'){
                logger.debug('响应通知成功。');
              }else{
                logger.error(`文件 ${filePath} 通知失败。`);
              }
            }).catch((e) => {
              logger.error(`响应文件 ${filePath} 通知异常:`, e.stack||e);   
            });
          }else{
            // back_url 为空，同步请求，触发通知事件
            util.emitNotice(fileSeq, fileJson);
          }
        }
        //删除请求文件
        await util.removeFile(filePath);
        break;
    }
  }
}